/*
 * @(#)PropertyMessageResources.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;

import org.apache.struts.util.MessageResourcesFactory;

/**
 * MessageResources class which holds the original ApplicationResources message and merged with 
 * CustomizedResources messages.
 * Purpose of the class is to minimize changes on ApplicationResources.properties during
 * project customization.
 * 
 * @author Ryan Kwan
 */
public class PropertyMessageResources extends org.apache.struts.util.PropertyMessageResources{

  public static final String REVISION = "$Revision: 1.2 $";

    
    /**
     * Application resources name for message customization.
     * e.g. If the application resources name is com.dcivision.resource.ApplicationResources, it's corresponding 
     * customization message resources is com.dcivision.resources.CustomizedResources
     */
    private static final String CUSTOMIZE_MESSAGE_NAME="CustomizedResources";
    
    /**
     * Construct a new PropertyMessageResources according to the
     * specified parameters.
     *
     * @param factory The MessageResourcesFactory that created us
     * @param config The configuration parameter for this MessageResources
     */
    public PropertyMessageResources(MessageResourcesFactory factory, String config) {
        super(factory, config);
    }
    
    /**
     * Construct a new PropertyMessageResources according to the
     * specified parameters.
     *
     * @param factory The MessageResourcesFactory that created us
     * @param config The configuration parameter for this MessageResources
     * @param returnNull The returnNull property we should initialize with
     */
    public PropertyMessageResources(MessageResourcesFactory factory,
                                    String config, boolean returnNull) {
        super(factory, config, returnNull);
    }    
    
    // ------------------------------------------------------ Protected Methods

    /**
     * Load the messages associated with the specified Locale key.  For this
     * implementation, the <code>config</code> property should contain a fully
     * qualified package and resource name, separated by periods, of a series
     * of property resources to be loaded from the class loader that created
     * this PropertyMessageResources instance.  This is exactly the same name
     * format you would use when utilizing the
     * <code>java.util.PropertyResourceBundle</code> class.
     * 
     * CUSTOMIZATION: merge an extra CustomizedResources.properties into 
     * the master ApplicationResources.properties
     *
     * @param localeKey Locale key for the messages to be retrieved
     */
    protected synchronized void loadLocale(String localeKey) {
        // Have we already attempted to load messages for this locale?
        if (locales.get(localeKey) != null) {
            return;
        }
        super.loadLocale(localeKey);

        // Set up to load the property resource for this locale key, if we can
        String name = config.replace('.', '/');
        
        
        // replace com/dcivision/resource/ApplicationResources 
        // to      com/dcivision/resource/CustomizedResources        
        name = name.substring(0,name.lastIndexOf('/')+1) + CUSTOMIZE_MESSAGE_NAME ;
        
        if (localeKey.length() > 0) {
            name += "_" + localeKey;
        }
        name += ".properties";
        InputStream is = null;
        Properties props = new Properties();
        
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader == null) {
            classLoader = this.getClass().getClassLoader();
        }
        
        is = classLoader.getResourceAsStream(name);
        if (is != null) {
            try {
                props.load(is);                
            } catch (IOException e) {
                log.error("loadLocale()", e);
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("loadLocale()", e);
                }
            }
        }

        // Copy the corresponding values into our cache
        if (props.size() < 1) {
            return;
        }
        
        //
        synchronized (messages) {
            Iterator names = props.keySet().iterator();
            while (names.hasNext()) {
                String key = (String) names.next();
                if (log.isTraceEnabled()) {
                    log.trace("  Saving customize message key '" + messageKey(localeKey, key));
                }
                messages.put(messageKey(localeKey, key), props.getProperty(key));
            }
        }
    }    

}
